﻿Imports PowerSong.SongDatabase.Legacy.Items
Imports System.IO
Imports System.Drawing

Friend NotInheritable Class DatabaseUpgrade

    Friend Shared Sub CheckSongCategories(ByVal database As Database)

        database.StartTransaction()
        Dim DefaultCategoryID As Guid = Guid.Empty

        ' Check all songs, ensuring they contain at least one category
        For Each SongID As Guid In database.Songs.GetAllSongIDs
            If database.Songs.GetSongCategories(SongID).Count = 0 Then

                ' "Upgrade" legacy databases to contain a default category if necessary
                If DefaultCategoryID = Guid.Empty Then DefaultCategoryID = database.Categories.GetOrCreateDefaultCategory()

                ' Assign the song the default category
                database.Songs.AddCategoryToSong(SongID, DefaultCategoryID)

            End If
        Next

        database.EndTransaction()

    End Sub

    Friend Shared Sub CheckDatabase(ByVal location As String, ByVal data As DataSet)

        ' Continually upgrade the database until it is the correct version
        Dim DatabaseVersion As String = String.Empty
        Do
            DatabaseVersion = data.Tables("Settings").Rows.Find("DatabaseVersion").Item("Value")

            ' Upgrade the database
            Select Case DatabaseVersion

                Case "0.9.3", "0.9.4", "0.9.5"
                    UpgradeEarlyVersion(location, data)

                Case "0.9.6"
                    UpgradeFrom096To098(location, data)

                Case "0.9.8"
                    UpgradeFrom098To099(location, data)

                Case Database.DATABASE_FILE_VERSION
                    ' Do nothing - the database is valid

                Case Else
                    Throw New ApplicationException("The version of the database (" + DatabaseVersion + ") is not as expected (" + Database.DATABASE_FILE_VERSION + ").")

            End Select

        Loop Until DatabaseVersion = Database.DATABASE_FILE_VERSION

    End Sub

    Private Shared Sub EnsureSettingExists(ByVal data As DataSet, _
                                           ByVal settingName As String, _
                                           ByVal defaultSettingValue As String)

        Dim SettingsTable As DataTable = data.Tables("Settings")
        If Not SettingsTable.Rows.Contains(settingName) Then
            SettingsTable.Rows.Add(settingName, defaultSettingValue)
        End If

    End Sub

    Private Shared Sub UpgradeEarlyVersion(ByVal location As String, ByVal data As DataSet)

        ' Add settings that should exist
        EnsureSettingExists(data, "DatabaseVersion", Database.DATABASE_FILE_VERSION)
        EnsureSettingExists(data, "ActiveBible", "KJV")
        EnsureSettingExists(data, "ShowSongPreviews", True.ToString)
        EnsureSettingExists(data, "ShowPreviewProjection", True.ToString)
        EnsureSettingExists(data, "ShowMainProjection", True.ToString)

        ' Add new style-based settings
        EnsureSettingExists(data, "NoticeFontName", "Arial")
        EnsureSettingExists(data, "NoticeFontSize", 55.ToString)
        EnsureSettingExists(data, "NoticeDefaultFontColour", Color.LightCyan.ToArgb.ToString)
        EnsureSettingExists(data, "NoticeDefaultBackgroundColour", Color.DarkSlateBlue.ToArgb.ToString)
        EnsureSettingExists(data, "NoticeFontStyle", FontStyle.Bold)
        EnsureSettingExists(data, "NoticeSpeed", 0.02.ToString)
        EnsureSettingExists(data, "NoticeTimeIn", 1000.ToString)
        EnsureSettingExists(data, "NoticeTimeOut", 1000.ToString)
        EnsureSettingExists(data, "NoticeDefaultDuration", 30.ToString)

        ' Create a projectlets table
        Dim Projectlets As DataTable = data.Tables.Add("Projectlets")
        Projectlets.Columns.Add("StyleID", GetType(Guid))
        Projectlets.Columns.Add("Component", GetType(String))
        Projectlets.Columns.Add("FontName", GetType(String))
        Projectlets.Columns.Add("FontSize", GetType(Double))
        Projectlets.Columns.Add("FontColour", GetType(Int32))
        Projectlets.Columns.Add("FontStyle", GetType(Int32))
        Projectlets.Columns.Add("FontEffect", GetType(Int32))
        Projectlets.Columns.Add("FontEffectColour", GetType(Int32))
        Projectlets.Columns.Add("AreaLeft", GetType(Double))
        Projectlets.Columns.Add("AreaTop", GetType(Double))
        Projectlets.Columns.Add("AreaWidth", GetType(Double))
        Projectlets.Columns.Add("AreaHeight", GetType(Double))
        Projectlets.Columns.Add("Alignment", GetType(Int32))
        Projectlets.Columns.Add("WhenToDisplay", GetType(Int32))

        ' Transform existing styles into PowerSong 0.9.6 based styles
        Dim Styles As DataTable = data.Tables("Styles")
        For Each StyleRow As DataRow In Styles.Rows

            ' Add the verse projectlet
            Projectlets.Rows.Add(StyleRow.Item("StyleID"), "Verse", StyleRow.Item("FontName"), StyleRow.Item("FontSize"), _
                                 StyleRow.Item("FontColour"), StyleRow.Item("FontStyle"), _
                                 StyleRow.Item("FontEffect"), StyleRow.Item("FontEffectColour"), _
                                 StyleRow.Item("MarginLeft"), StyleRow.Item("MarginTop"), _
                                 StyleRow.Item("MarginWidth"), StyleRow.Item("MarginHeight"), _
                                 [Enum].Parse(GetType(Style.ETextAlignment), StyleRow.Item("Alignment")), _
                                 Style.EDisplayOption.Always)

            ' Add default other projectlets
            Projectlets.Rows.Add(StyleRow.Item("StyleID"), "Copyright", "Verdana", 32, Color.White.ToArgb, _
                                 FontStyle.Italic, Style.ETextEffect.None, _
                                 Color.Black.ToArgb, 0.05, 0.85, 0.9, 0.15, _
                                 Style.ETextAlignment.BottomMiddle, _
                                 Style.EDisplayOption.Never)
            Projectlets.Rows.Add(StyleRow.Item("StyleID"), "Title", "Verdana", 40, Color.White.ToArgb, _
                                 FontStyle.Bold, Style.ETextEffect.None, _
                                 Color.Black.ToArgb, 0, 0, 1, 0.2, _
                                 Style.ETextAlignment.TopLeft, _
                                 Style.EDisplayOption.Never)

        Next

        ' Remove old style-based data columns
        Styles.Columns.Remove(Styles.Columns("MarginLeft"))
        Styles.Columns.Remove(Styles.Columns("MarginTop"))
        Styles.Columns.Remove(Styles.Columns("MarginWidth"))
        Styles.Columns.Remove(Styles.Columns("MarginHeight"))
        Styles.Columns.Remove(Styles.Columns("FontName"))
        Styles.Columns.Remove(Styles.Columns("FontSize"))
        Styles.Columns.Remove(Styles.Columns("FontColour"))
        Styles.Columns.Remove(Styles.Columns("FontStyle"))
        Styles.Columns.Remove(Styles.Columns("FontEffect"))
        Styles.Columns.Remove(Styles.Columns("FontEffectColour"))
        Styles.Columns.Remove(Styles.Columns("Alignment"))

        ' Remove index so that a new one is created
        Dim IndexFileName As String = location + "\Songs.Index"
        If File.Exists(IndexFileName) Then File.Delete(IndexFileName)

        ' Complete the upgrade
        SetDatabaseVersion(location, data, "0.9.6")

    End Sub

    Private Shared Sub UpgradeFrom096To098(ByVal location As String, ByVal data As DataSet)

        ' Add settings that should exist
        EnsureSettingExists(data, "CopyrightYear", Now.Year.ToString)
        EnsureSettingExists(data, "CopyrightOwner", "None")
        EnsureSettingExists(data, "ExternalLicenseNumber", "None")
        EnsureSettingExists(data, "EnableLogging", False.ToString)

        ' Create a new data column for projectlet content
        Dim Table As DataTable = data.Tables("Projectlets")
        Table.Columns.Add("Content")

        ' Assign default values for the new content column
        For Each Row As DataRow In Table.Rows
            Select Case Row.Item("Component").ToString
                Case "Title" : Row.Item("Content") = "{Title}"
                Case "Verse" : Row.Item("Content") = "{Verse}"
                Case "Copyright" : Row.Item("Content") = "{SimpleCopyright}"
                Case Else : Throw New Exception("An invalid projectlet has been encountered. Please contact the author.")
            End Select
        Next

        ' Complete the upgrade
        SetDatabaseVersion(location, data, "0.9.8")

    End Sub

    Private Shared Sub UpgradeFrom098To099(ByVal location As String, ByVal data As DataSet)

        ' Migrate license details to the new license table
        Dim SettingsTable As DataTable = data.Tables("Settings")
        Dim CopyrightYearRow As DataRow = SettingsTable.Rows.Find("CopyrightYear")
        Dim CopyrightOwnerRow As DataRow = SettingsTable.Rows.Find("CopyrightOwner")
        Dim ExternalLicenseNumberRow As DataRow = SettingsTable.Rows.Find("ExternalLicenseNumber")

        ' Create the new license table
        Dim LicenseTable As DataTable = data.Tables.Add("Licenses")
        LicenseTable.Columns.Add("LicenseID", GetType(Guid))
        LicenseTable.Columns.Add("Name")
        LicenseTable.Columns.Add("Details")
        LicenseTable.Columns.Add("Number")
        Dim LicenseRow As DataRow = LicenseTable.NewRow
        LicenseRow.Item("LicenseID") = Guid.NewGuid
        LicenseRow.Item("Name") = "Default License"
        LicenseRow.Item("Details") = CopyrightOwnerRow.Item("Value").ToString + Environment.NewLine + "Year: " + CopyrightYearRow.Item("Value").ToString
        LicenseRow.Item("Number") = ExternalLicenseNumberRow.Item("Value").ToString
        LicenseTable.Rows.Add(LicenseRow)

        ' Delete old license related settings
        SettingsTable.Rows.Remove(CopyrightYearRow)
        SettingsTable.Rows.Remove(CopyrightOwnerRow)
        SettingsTable.Rows.Remove(ExternalLicenseNumberRow)
        data.AcceptChanges()

        ' Complete the upgrade
        SetDatabaseVersion(location, data, "0.9.9")

    End Sub

    Private Shared Sub SetDatabaseVersion(ByVal location As String, ByVal data As DataSet, ByVal version As String)

        ' Set the database version and save the database file
        data.Tables("Settings").Rows.Find("DatabaseVersion").Item("Value") = version
        data.WriteXml(location + "\Database.xml")

    End Sub

End Class
